home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / utilities / easyproc2.lha / EasyProcess / hc / data.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-05  |  6.7 KB  |  377 lines

  1. /*
  2.  *    Data functions.
  3.  *
  4.  */
  5.  
  6. #include "hc.h"
  7.  
  8. struct CircBuffer
  9. {
  10.     UBYTE Mem[4096];
  11.     UWORD Read;
  12.     UWORD Write;
  13.     UWORD Size;
  14.     UWORD OverRun;
  15. };
  16.  
  17. void WriteData (struct CircBuffer *, UWORD);
  18. void ServeWaiter (void);
  19. UWORD Truth (UWORD Value, UBYTE *Buffer);
  20.  
  21. static struct CircBuffer *FileBuffer;
  22. static UBYTE *WriteBuffer[2];
  23. static UWORD FreeBuffer, Modem = 1, ToHC, FromHC;
  24.  
  25. /*
  26.  *    UWORD OpenData (void)    void CloseData (void)
  27.  *
  28.  *        Alloc and free the memory needed for data manipulation.
  29.  */
  30.  
  31. UWORD OpenData (void)
  32. {
  33.     FileBuffer = AllocMem (sizeof (struct CircBuffer) * NUM_HC, MEMF_CLEAR);
  34.     if (FileBuffer)
  35.     {
  36.         WriteBuffer[0] = AllocMem (4096, 0L);
  37.         if (WriteBuffer[0])
  38.         {
  39.             WriteBuffer[1] = AllocMem (4096, 0L);
  40.             if (WriteBuffer[1])
  41.             {
  42.                 return 1;
  43.             }
  44.         }
  45.     }
  46. DB    else
  47. DB    {
  48. DB        Say ("FileBuffer allocation failed.\n");
  49. DB    }
  50.  
  51.     CloseData ();
  52.     return 0;
  53. }
  54.  
  55. void CloseData (void)
  56. {
  57.     if (WriteBuffer[1]) FreeMem (WriteBuffer[1], 4096);
  58.     if (WriteBuffer[0]) FreeMem (WriteBuffer[0], 4096);
  59.     if (FileBuffer) FreeMem (FileBuffer, sizeof (struct CircBuffer) * NUM_HC);
  60.  
  61.     FileBuffer = NULL;
  62.     WriteBuffer[0] = NULL;
  63.     WriteBuffer[1] = NULL;
  64. }
  65.  
  66.  
  67. /*
  68.  *    UWORD PutData (UWORD File, UBYTE *Buffer, UWORD Size)
  69.  *
  70.  *        Put a HC11 address between each byte sent to the serial port.  The
  71.  *        address is a lower nibble containing the id of the sender and a
  72.  *        higher nibble containg the id of the receiver.
  73.  */
  74.  
  75. UWORD PutData (UWORD File, UBYTE *Buffer, UWORD Size)
  76. {
  77.     UWORD SizeCount;
  78.     UWORD BufferCount;
  79.  
  80.     if (File == BAUD)
  81.     {
  82.         SetBaud (atoi (Buffer));
  83.         return Size;
  84.     }
  85.     else if (File == FROM)
  86.     {
  87.         FromHC = Truth (FromHC, Buffer);
  88.         return Size;
  89.     }
  90.     else if (File == TO)
  91.     {
  92.         ToHC = Truth (ToHC, Buffer);
  93.         return Size;
  94.     }
  95.     else if (File == MODEM)
  96.     {
  97.         Modem = Truth (Modem, Buffer);
  98.         return Size;
  99.     }
  100.     else if (File > 0 && File <= NUM_HC)
  101.     {
  102.  
  103.         File = (File << 3) | 0x80;
  104.         SizeCount = Size;
  105.         BufferCount = 0;
  106.     
  107.         while (SizeCount--)
  108.         {
  109.             if (ToHC)
  110.             {
  111. DB                sprintf (dbi.Msg, "Sending file iden byte: %x.\n", File);
  112. DB                Say (dbi.Msg);
  113.                 WriteBuffer[FreeBuffer][BufferCount++] = File;
  114.             }
  115.  
  116.             if (Modem == 1 && *Buffer == 10)
  117.                 *Buffer = 13;
  118.  
  119.             WriteBuffer[FreeBuffer][BufferCount++] = *Buffer++;
  120.             if (BufferCount == 4096)
  121.             {
  122.                 WriteSer (WriteBuffer[FreeBuffer], 4096);
  123.                 BufferCount = 0;
  124.                 FreeBuffer = (FreeBuffer + 1) & 1;
  125.             }
  126.         }
  127.  
  128.         if (BufferCount)
  129.         {
  130.             WriteSer (WriteBuffer[FreeBuffer], BufferCount);
  131.             FreeBuffer = (FreeBuffer + 1) & 1;
  132.         }
  133.  
  134.         return Size;
  135.     }
  136.     else
  137.     {
  138.         return 0;
  139.     }
  140. }
  141.  
  142.  
  143. /*
  144.  *    UWORD Truth (UWORD Value, UBYTE *Buffer)
  145.  *
  146.  *        Check the truth contained in a string, and return true, false or the
  147.  *        old value.
  148.  */
  149.  
  150. UWORD Truth (UWORD Value, UBYTE *Buffer)
  151. {
  152.     if (*Buffer == '0')
  153.         return 0;
  154.     else if (*Buffer == '1')
  155.         return 1;
  156.     else
  157.         return Value;
  158. }
  159.  
  160.  
  161. /*
  162.  *    UWORD GetData (UWORD File, UBYTE *Buffer, UWORD Size)
  163.  *
  164.  *        Check which file is read and take that much data from the buffers.
  165.  *        They are filled by the serial routines.
  166.  */
  167.  
  168. UWORD GetData (UWORD File, UBYTE *Buffer, UWORD Size)
  169. {
  170.     struct CircBuffer *b;
  171.     UWORD rcount = Size;
  172.  
  173.     if (File == 0 || File > NUM_HC)
  174.         return 0;
  175.  
  176.     /*
  177.      *    Get the data associated with the file number.
  178.      */
  179.  
  180.      b = &FileBuffer[File - 1];
  181.  
  182.     /*
  183.      *    No data -> wait for more by return ing minus one (-1).
  184.      */
  185.  
  186.     if (0 == b->Size)
  187.         return -1;
  188.  
  189.     /*
  190.      *    Transfer as much as we have.
  191.      */
  192.  
  193.     while (rcount > 0 && b->Size > 0)
  194.     {
  195.         *Buffer++ = b->Mem[b->Read++];
  196.         b->Read &= 0x0fff;
  197.         rcount--;
  198.         b->Size--;
  199.     }
  200.  
  201.     return Size - rcount;
  202. }
  203.  
  204.  
  205. /*
  206.  *    UWORD DataSize (UWORD File)
  207.  *
  208.  *        Return the current size of the file, which is the amount of data
  209.  *        pending in the circular buffer.
  210.  */
  211.  
  212. UWORD DataSize (UWORD File)
  213. {
  214.     switch (File)
  215.     {
  216.         case ROOT:
  217.             return 0;
  218.         case MODEM:
  219.             return Modem;
  220.         case FROM:
  221.             return FromHC;
  222.         case TO:
  223.             return ToHC;
  224.         case BAUD:
  225.             return GetBaud ();
  226.         case HC1:
  227.         case HC2:
  228.         case HC3:
  229.         case HC4:
  230.         case HC5:
  231.         case HC6:
  232.         case LOOP:
  233.             return FileBuffer[File-1].Size;
  234.         default:
  235.             return -1;
  236.     }
  237. }
  238.  
  239.  
  240. /*
  241.  *    void ClassData (UBYTE *Buffer, UWORD Size)
  242.  *
  243.  *        This parse a buffer as pairs of bytes.  The first byte contain the
  244.  *        id of the sender in the low nibble and the id of the receiver in
  245.  *        the high nibble.
  246.  *
  247.  *        If the data is ours (id == 0), then we put the data in the second
  248.  *        byte in its buffer, if it's for someone else (id != 0), we resend
  249.  *        it out of the srial port.
  250.  *
  251.  *        The code check for over-run of the circular buffer for each id and
  252.  *        set the head of the read in accordance to the new position of the
  253.  *        write head.
  254.  */
  255.  
  256. void ClassData (UBYTE *Buffer, UWORD Size)
  257. {
  258.     UWORD i;
  259.  
  260.     if (FromHC)
  261.     {
  262.         while (Size > 1)
  263.         {
  264.             i = (UWORD)Buffer[0];
  265.             if (i & 0x80)
  266.             {
  267.                 i &= 0x3F;
  268.                 if (i > 0 && i <= NUM_HC)
  269.                 {
  270. DB                    Say ("Data decoded from HC11.\n");
  271.                     WriteData (&FileBuffer[i - 1], (UWORD)Buffer[1]);
  272.                 }
  273.                 else if (i & 0x07)
  274.                 {
  275. DB                    sprintf (dbi.Msg, "Data passing through (i == %x).\n", i);
  276. DB                    Say (dbi.Msg);
  277. //                    WriteSer (Buffer, 2);
  278.                 }
  279.                 else
  280.                 {
  281.                     /*
  282.                      *    Data we sent somehow looped the loop...
  283.                      */
  284. DB                    Say ("Data looped around.\n");
  285.                     WriteData (&FileBuffer[LOOP-1], (UWORD)Buffer[1]);
  286.                 }
  287.                 Size -= 2;
  288.                 Buffer += 2;
  289.             }
  290.             else
  291.             {
  292. DB                Say ("Trying to synchronize.\n");
  293.                 SyncSer ();
  294.                 Size -= 1;
  295.                 Buffer += 1;
  296.             }
  297.         }
  298.     }
  299.     else
  300.     {
  301.         while (Size--)
  302.         {
  303.             WriteData (FileBuffer, (UWORD)*Buffer);
  304.             Buffer++;
  305.         }
  306.     }
  307.  
  308.     for (i = 0; i < NUM_HC; i++)
  309.     {
  310.         if (FileBuffer[i].OverRun)
  311.         {
  312.             FileBuffer[i].Read = (FileBuffer[i].Write + 1) & 0x0fff;
  313.             FileBuffer[i].OverRun = 0;
  314.         }
  315.     }
  316.  
  317.     ServeWaiter ();
  318. }
  319.  
  320.  
  321. /*
  322.  *    void WriteData (struct CircBuffer *b, UWORD c)
  323.  *
  324.  *        Put a byte of data in a circular buffer and check for overflow.
  325.  */
  326.  
  327. void WriteData (struct CircBuffer *b, UWORD c)
  328. {
  329.     if (Modem == 1)
  330.     {
  331.         if (c == 10)
  332.             return;
  333.         else if (c == 13)
  334.             c = 10;
  335.     }
  336.     b->Mem[b->Write++] = c;
  337.     b->Write &= 0x0fff;
  338.     if (b->Write == b->Read)
  339.         b->OverRun = 1;
  340.     b->Size = (b->Size + 1) & 0x0FFF;
  341. }
  342.  
  343.  
  344. /*
  345.  *    void ServeWaiter (void)
  346.  *
  347.  *        Serve packets that are waiting for data.  The REALLY nice thing here
  348.  *        is that since the packet was waiting, no data was in the buffer, and
  349.  *        since this function is called by ClassData, which is itself always
  350.  *        called when there's been 4096 bytes of data (maximum) arrived, we're
  351.  *        sure that we lose no data...
  352.  */
  353.  
  354. void ServeWaiter (void)
  355. {
  356.     struct DosPacket *Packet;
  357.     struct Node *Node, *Next;
  358.  
  359. DB    Say ("Serving waiters.\n");
  360.  
  361.     for (Node = ReadList.lh_Head; Node->ln_Succ != NULL; Node = Next)
  362.     {
  363.         Next = Node->ln_Succ;
  364.         Packet = (struct DosPacket *)Node->ln_Name;
  365.         if (Packet != NULL)
  366.         {
  367.             if (FileBuffer[Packet->dp_Arg1 - 1].Size > 0)
  368.             {
  369. DB                Say ("Replying to waiter.\n");
  370.                 Remove (Node);
  371.                 Packet->dp_Res1 = GetData (Packet->dp_Arg1, (UBYTE *)Packet->dp_Arg2, Packet->dp_Arg3);
  372.                 ReturnPacket (Packet, Process);
  373.             }
  374.         }
  375.     }
  376. }
  377.